package pri.zjy.tree;

import pri.zjy.tree.model.TreeNode;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author zhangjy
 * @description 路径总和ii
 * @date 2025/4/18 10:44
 */
public class PathSum_113 {

    public static void main(String[] args) {
        PathSum_113 pathSum113 = new PathSum_113();

        TreeNode eleven_left_seven = new TreeNode(7, null, null);
        TreeNode eleven_right_two = new TreeNode(2, null, null);
        TreeNode four_l_eleven = new TreeNode(11, eleven_left_seven, eleven_right_two);
        TreeNode root_l_four = new TreeNode(4, four_l_eleven, null);

        TreeNode four_l_five = new TreeNode(5, null, null);
        TreeNode four_r_one = new TreeNode(1, null, null);
        TreeNode eight_l_thirteen = new TreeNode(13, null, null);
        TreeNode eight_r_four = new TreeNode(4, four_l_five, four_r_one);
        TreeNode root_r_eight = new TreeNode(8, eight_l_thirteen, eight_r_four);

        TreeNode root = new TreeNode(5, root_l_four, root_r_eight);

        System.out.println(pathSum113.pathSum(root, 22));

    }

    /**
     * dmsxl：dfs-递归
     * <p>
     * 显示回溯
     */
    public List<List<Integer>> pathSum2(TreeNode root, int targetSum) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null) return res; // 非空判断

        List<Integer> path = new LinkedList<>();
        preOrderDfs2(root, targetSum, res, path);
        return res;
    }

    public void preOrderDfs2(TreeNode root, int targetSum, List<List<Integer>> res, List<Integer> path) {
        path.add(root.val);
        // 遇到了叶子节点
        if (root.left == null && root.right == null) {
            // 找到了和为 targetsum 的路径
            if (targetSum - root.val == 0) {
                res.add(new ArrayList<>(path));
            }
            return; // 如果和不为 targetsum，返回
        }

        if (root.left != null) {
            preOrderDfs2(root.left, targetSum - root.val, res, path);
            path.remove(path.size() - 1); // 回溯
        }
        if (root.right != null) {
            preOrderDfs2(root.right, targetSum - root.val, res, path);
            path.remove(path.size() - 1); // 回溯
        }
    }

    /**
     * 个解：dfs-递归-回溯
     * 同dmsxl一致。
     * <p>
     * 思路：
     * 1.要遍历整个树，找到所有路径，所以递归函数不要返回值！
     * 2.需要一个全局遍历记录本条路径，且因为是全局变量，所以需要回溯。
     */
    List<List<Integer>> ans = new ArrayList<>();

    List<Integer> nodePath = new ArrayList<>();

    public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
        dfs(root, targetSum);
        return ans;
    }

    public void dfs(TreeNode node, int count) {
        if (node == null) return;

        count -= node.val;
        nodePath.add(node.val);
        if (node.left == null && node.right == null) {
            // 叶子节点，且找到满足条件的路径
            if (count == 0) {
                // 记录满足条件的路径
                // 此时要记录一个新对象curNodePath，因为nodePath一直在变。如果记录nodePath，那回溯到最后，里面只有一个根节点的节点值
                List<Integer> curNodePath = new ArrayList<>(nodePath);
                ans.add(curNodePath);
            }
            return;
        }

        // 显示回溯
        dfs(node.left, count);
        if (node.left != null) nodePath.remove(nodePath.size() - 1);

        dfs(node.right, count);
        if (node.right != null) nodePath.remove(nodePath.size() - 1);
    }

}
